package com.koushikdutta.ion;

import android.app.ProgressDialog;
import android.net.Uri;
import android.net.Uri.Builder;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.widget.ProgressBar;
import com.google.gson.JsonObject;
import com.koushikdutta.async.AsyncServer;
import com.koushikdutta.async.ByteBufferList;
import com.koushikdutta.async.DataEmitter;
import com.koushikdutta.async.DataSink;
import com.koushikdutta.async.DataTrackingEmitter;
import com.koushikdutta.async.DataTrackingEmitter.DataTracker;
import com.koushikdutta.async.FilteredDataEmitter;
import com.koushikdutta.async.Util;
import com.koushikdutta.async.callback.CompletedCallback;
import com.koushikdutta.async.future.Cancellable;
import com.koushikdutta.async.future.Future;
import com.koushikdutta.async.future.FutureCallback;
import com.koushikdutta.async.future.SimpleFuture;
import com.koushikdutta.async.future.TransformFuture;
import com.koushikdutta.async.http.AsyncHttpRequest;
import com.koushikdutta.async.http.Multimap;
import com.koushikdutta.async.http.body.AsyncHttpRequestBody;
import com.koushikdutta.async.http.body.UrlEncodedFormBody;
import com.koushikdutta.async.http.libcore.RawHeaders;
import com.koushikdutta.async.parser.AsyncParser;
import com.koushikdutta.async.parser.ByteBufferListParser;
import com.koushikdutta.async.stream.FileDataSink;
import com.koushikdutta.ion.Loader.LoaderEmitter;
import com.koushikdutta.ion.builder.Builders.Any.B;
import com.koushikdutta.ion.builder.Builders.Any.F;
import com.koushikdutta.ion.builder.Builders.Any.M;
import com.koushikdutta.ion.builder.Builders.Any.U;
import com.koushikdutta.ion.builder.LoadBuilder;
import com.koushikdutta.ion.future.ResponseFuture;
import com.koushikdutta.ion.gson.GsonBody;
import com.koushikdutta.ion.gson.GsonObjectParser;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

class IonRequestBuilder implements B, F, M, U, LoadBuilder<B> {
    static final /* synthetic */ boolean $assertionsDisabled = (!IonRequestBuilder.class.desiredAssertionStatus());
    AsyncHttpRequestBody body;
    Multimap bodyParameters;
    ContextReference contextReference;
    boolean followRedirect = true;
    ArrayList<WeakReference<Object>> groups;
    Handler handler = Ion.mainHandler;
    RawHeaders headers;
    HeadersCallback headersCallback;
    Ion ion;
    LoadRequestCallback loadRequestCallback;
    int logLevel;
    String logTag;
    String method = "GET";
    boolean methodWasSet;
    boolean noCache;
    ProgressCallback progress;
    WeakReference<ProgressBar> progressBar;
    WeakReference<ProgressDialog> progressDialog;
    ProgressCallback progressHandler;
    String proxyHost;
    int proxyPort;
    Multimap query;
    int timeoutMilliseconds = 30000;
    ProgressCallback uploadProgress;
    ProgressBar uploadProgressBar;
    ProgressDialog uploadProgressDialog;
    ProgressCallback uploadProgressHandler;
    String uri;

    interface LoadRequestCallback {
        boolean loadRequest(AsyncHttpRequest asyncHttpRequest);
    }

    class EmitterTransform<T> extends TransformFuture<T, LoaderEmitter> implements ResponseFuture<T> {
        Runnable cancelCallback;
        DataEmitter emitter;
        AsyncHttpRequest finalRequest;
        RawHeaders headers;
        AsyncHttpRequest initialRequest;
        int loadedFrom;

        public Response<T> getResponse(Exception e, T result) {
            Response<T> response = new Response();
            response.headers = this.headers;
            response.request = this.finalRequest;
            response.result = result;
            response.exception = e;
            return response;
        }

        public Future<Response<T>> withResponse() {
            final SimpleFuture<Response<T>> ret = new SimpleFuture();
            setCallback(new FutureCallback<T>() {
                public void onCompleted(Exception e, T result) {
                    if (EmitterTransform.this.emitter != null) {
                        ret.setComplete(EmitterTransform.this.getResponse(e, result));
                    } else {
                        ret.setComplete(e, null);
                    }
                }
            });
            ret.setParent((Cancellable) this);
            return ret;
        }

        public int loadedFrom() {
            return this.loadedFrom;
        }

        public EmitterTransform(Runnable cancelCallback) {
            this.cancelCallback = cancelCallback;
            IonRequestBuilder.this.ion.addFutureInFlight(this, IonRequestBuilder.this.contextReference.getContext());
            if (IonRequestBuilder.this.groups != null) {
                Iterator i$ = IonRequestBuilder.this.groups.iterator();
                while (i$.hasNext()) {
                    Object group = ((WeakReference) i$.next()).get();
                    if (group != null) {
                        IonRequestBuilder.this.ion.addFutureInFlight(this, group);
                    }
                }
            }
        }

        protected void cancelCleanup() {
            super.cancelCleanup();
            if (this.emitter != null) {
                this.emitter.close();
            }
            if (this.cancelCallback != null) {
                this.cancelCallback.run();
            }
        }

        protected void error(Exception e) {
            IonRequestBuilder.this.postExecute(this, e, null);
        }

        protected void transform(LoaderEmitter emitter) throws Exception {
            DataTrackingEmitter tracker;
            this.emitter = emitter.getDataEmitter();
            this.loadedFrom = emitter.loadedFrom();
            this.headers = emitter.getHeaders();
            this.finalRequest = emitter.getRequest();
            if (IonRequestBuilder.this.headersCallback != null) {
                final RawHeaders headers = emitter.getHeaders();
                AsyncServer.post(IonRequestBuilder.this.handler, new Runnable() {
                    public void run() {
                        IonRequestBuilder.this.headersCallback.onHeaders(headers);
                    }
                });
            }
            final long total = emitter.length();
            if (this.emitter instanceof DataTrackingEmitter) {
                tracker = (DataTrackingEmitter) this.emitter;
            } else {
                tracker = new FilteredDataEmitter();
                tracker.setDataEmitter(this.emitter);
            }
            this.emitter = tracker;
            tracker.setDataTracker(new DataTracker() {
                static final /* synthetic */ boolean $assertionsDisabled = (!IonRequestBuilder.class.desiredAssertionStatus());
                int lastPercent;

                public void onData(final int totalBytesRead) {
                    if (!$assertionsDisabled && Thread.currentThread() == Looper.getMainLooper().getThread()) {
                        throw new AssertionError();
                    } else if (IonRequestBuilder.this.contextReference.isAlive() != null) {
                        EmitterTransform.this.initialRequest.logd("context has died, cancelling");
                        EmitterTransform.this.cancelSilently();
                    } else {
                        final int percent = (int) ((((float) totalBytesRead) / ((float) total)) * 100.0f);
                        if (!((IonRequestBuilder.this.progressBar == null && IonRequestBuilder.this.progressDialog == null) || percent == this.lastPercent)) {
                            AsyncServer.post(Ion.mainHandler, new Runnable() {
                                public void run() {
                                    if (IonRequestBuilder.this.progressBar != null) {
                                        ProgressBar bar = (ProgressBar) IonRequestBuilder.this.progressBar.get();
                                        if (bar != null) {
                                            bar.setProgress(percent);
                                        }
                                    }
                                    if (IonRequestBuilder.this.progressDialog != null) {
                                        ProgressDialog dlg = (ProgressDialog) IonRequestBuilder.this.progressDialog.get();
                                        if (dlg != null) {
                                            dlg.setProgress(percent);
                                        }
                                    }
                                }
                            });
                        }
                        this.lastPercent = percent;
                        if (IonRequestBuilder.this.progress != null) {
                            IonRequestBuilder.this.progress.onProgress((long) totalBytesRead, total);
                        }
                        if (IonRequestBuilder.this.progressHandler != null) {
                            AsyncServer.post(Ion.mainHandler, new Runnable() {
                                public void run() {
                                    if (!EmitterTransform.this.isCancelled() && !EmitterTransform.this.isDone()) {
                                        IonRequestBuilder.this.progressHandler.onProgress((long) totalBytesRead, total);
                                    }
                                }
                            });
                        }
                    }
                }
            });
        }
    }

    public IonRequestBuilder(ContextReference contextReference, Ion ion) {
        String alive = contextReference.isAlive();
        if (alive != null) {
            Log.w("Ion", "Building request with dead context: " + alive);
        }
        this.ion = ion;
        this.contextReference = contextReference;
    }

    public IonRequestBuilder load(String url) {
        return loadInternal("GET", url);
    }

    private IonRequestBuilder loadInternal(String method, String url) {
        this.method = method;
        if (!TextUtils.isEmpty(url) && url.startsWith("/")) {
            url = new File(url).toURI().toString();
        }
        this.uri = url;
        return this;
    }

    private RawHeaders getHeaders() {
        if (this.headers == null) {
            this.headers = new RawHeaders();
            AsyncHttpRequest.setDefaultHeaders(this.headers, this.uri == null ? null : Uri.parse(this.uri));
        }
        return this.headers;
    }

    public IonRequestBuilder addHeader(String name, String value) {
        if (value != null) {
            getHeaders().add(name, value);
        }
        return this;
    }

    public IonRequestBuilder setTimeout(int timeoutMilliseconds) {
        this.timeoutMilliseconds = timeoutMilliseconds;
        return this;
    }

    public IonRequestBuilder setHandler(Handler handler) {
        this.handler = handler;
        return this;
    }

    private <T> IonRequestBuilder setBody(AsyncHttpRequestBody<T> body) {
        if (!this.methodWasSet) {
            this.method = "POST";
        }
        this.body = body;
        return this;
    }

    public IonRequestBuilder setJsonObjectBody(JsonObject jsonObject) {
        return setBody(new GsonBody(this.ion.configure().getGson(), jsonObject));
    }

    private <T> void postExecute(final EmitterTransform<T> future, final Exception ex, final T value) {
        Runnable runner = new Runnable() {
            public void run() {
                String deadReason = IonRequestBuilder.this.contextReference.isAlive();
                if (deadReason != null) {
                    future.initialRequest.logd("context has died: " + deadReason);
                    future.cancelSilently();
                } else if (ex != null) {
                    future.setComplete(ex);
                } else {
                    future.setComplete(value);
                }
            }
        };
        if (this.handler == null) {
            this.ion.httpClient.getServer().post(runner);
        } else {
            AsyncServer.post(this.handler, runner);
        }
    }

    private Uri prepareURI() {
        Uri uri;
        try {
            if (this.query != null) {
                Builder builder = Uri.parse(this.uri).buildUpon();
                for (String key : this.query.keySet()) {
                    for (String value : (List) this.query.get(key)) {
                        builder = builder.appendQueryParameter(key, value);
                    }
                }
                uri = builder.build();
            } else {
                uri = Uri.parse(this.uri);
            }
        } catch (Exception e) {
            uri = null;
        }
        if (uri == null || uri.getScheme() == null) {
            return null;
        }
        return uri;
    }

    private AsyncHttpRequest prepareRequest(Uri uri, AsyncHttpRequestBody wrappedBody) {
        AsyncHttpRequest request = this.ion.configure().getAsyncHttpRequestFactory().createAsyncHttpRequest(uri, this.method, this.headers);
        request.setFollowRedirect(this.followRedirect);
        request.setBody(wrappedBody);
        request.setLogging(this.ion.logtag, this.ion.logLevel);
        if (this.logTag != null) {
            request.setLogging(this.logTag, this.logLevel);
        }
        request.enableProxy(this.proxyHost, this.proxyPort);
        request.setTimeout(this.timeoutMilliseconds);
        request.logd("preparing request");
        return request;
    }

    private <T> void getLoaderEmitter(final EmitterTransform<T> ret) {
        Uri uri = prepareURI();
        if (uri == null) {
            ret.setComplete(new Exception("Invalid URI"));
            return;
        }
        AsyncHttpRequestBody wrappedBody = this.body;
        if (!(this.uploadProgressHandler == null && this.uploadProgressBar == null && this.uploadProgress == null && this.uploadProgressDialog == null)) {
            wrappedBody = new RequestBodyUploadObserver(this.body, new ProgressCallback() {
                static final /* synthetic */ boolean $assertionsDisabled = (!IonRequestBuilder.class.desiredAssertionStatus());

                public void onProgress(long downloaded, long total) {
                    if ($assertionsDisabled || Thread.currentThread() != Looper.getMainLooper().getThread()) {
                        int percent = (int) ((((float) downloaded) / ((float) total)) * 100.0f);
                        if (IonRequestBuilder.this.uploadProgressBar != null) {
                            IonRequestBuilder.this.uploadProgressBar.setProgress(percent);
                        }
                        if (IonRequestBuilder.this.uploadProgressDialog != null) {
                            IonRequestBuilder.this.uploadProgressDialog.setProgress(percent);
                        }
                        if (IonRequestBuilder.this.uploadProgress != null) {
                            IonRequestBuilder.this.uploadProgress.onProgress(downloaded, total);
                        }
                        if (IonRequestBuilder.this.uploadProgressHandler != null) {
                            final long j = downloaded;
                            final long j2 = total;
                            AsyncServer.post(Ion.mainHandler, new Runnable() {
                                public void run() {
                                    if (!ret.isCancelled() && !ret.isDone()) {
                                        IonRequestBuilder.this.uploadProgressHandler.onProgress(j, j2);
                                    }
                                }
                            });
                            return;
                        }
                        return;
                    }
                    throw new AssertionError();
                }
            });
        }
        AsyncHttpRequest request = prepareRequest(uri, wrappedBody);
        ret.initialRequest = request;
        resolveAndLoadRequest(request, ret);
    }

    <T> void resolveAndLoadRequest(final AsyncHttpRequest request, final EmitterTransform<T> ret) {
        Future<AsyncHttpRequest> resolved = resolveRequest(request, ret);
        if (resolved != null) {
            resolved.setCallback(new FutureCallback<AsyncHttpRequest>() {
                public void onCompleted(Exception e, AsyncHttpRequest result) {
                    if (e != null) {
                        ret.setComplete(e);
                        return;
                    }
                    ret.finalRequest = result;
                    IonRequestBuilder.this.resolveAndLoadRequest(result, ret);
                }
            });
        } else if (Looper.getMainLooper().getThread() != Thread.currentThread()) {
            AsyncServer.post(Ion.mainHandler, new Runnable() {
                public void run() {
                    IonRequestBuilder.this.invokeLoadRequest(request, ret);
                }
            });
        } else {
            invokeLoadRequest(request, ret);
        }
    }

    <T> void invokeLoadRequest(AsyncHttpRequest request, EmitterTransform<T> ret) {
        if (this.loadRequestCallback == null || this.loadRequestCallback.loadRequest(request)) {
            loadRequest(request, ret);
        }
    }

    <T> void loadRequest(AsyncHttpRequest request, EmitterTransform<T> ret) {
        Iterator i$ = this.ion.loaders.iterator();
        while (i$.hasNext()) {
            Loader loader = (Loader) i$.next();
            Future<DataEmitter> emitter = loader.load(this.ion, request, ret);
            if (emitter != null) {
                request.logi("Using loader: " + loader);
                ret.setParent((Cancellable) emitter);
                return;
            }
        }
        ret.setComplete(new Exception("Unknown uri scheme"));
    }

    <T> Future<AsyncHttpRequest> resolveRequest(AsyncHttpRequest request, EmitterTransform<T> emitterTransform) {
        Iterator i$ = this.ion.loaders.iterator();
        while (i$.hasNext()) {
            Future<AsyncHttpRequest> resolved = ((Loader) i$.next()).resolve(this.contextReference.getContext(), this.ion, request);
            if (resolved != null) {
                return resolved;
            }
        }
        return null;
    }

    <T> EmitterTransform<T> execute(DataSink sink, boolean close, T result, Runnable cancel) {
        final boolean z = close;
        final DataSink dataSink = sink;
        final T t = result;
        EmitterTransform<T> ret = new EmitterTransform<T>(cancel) {
            EmitterTransform<T> self = this;

            protected void cleanup() {
                super.cleanup();
                if (z) {
                    dataSink.end();
                }
            }

            protected void transform(LoaderEmitter emitter) throws Exception {
                super.transform(emitter);
                Util.pump(this.emitter, dataSink, new CompletedCallback() {
                    public void onCompleted(Exception ex) {
                        IonRequestBuilder.this.postExecute(AnonymousClass5.this.self, ex, t);
                    }
                });
            }
        };
        getLoaderEmitter(ret);
        return ret;
    }

    <T> EmitterTransform<T> execute(AsyncParser<T> parser) {
        return execute(parser, null);
    }

    <T> EmitterTransform<T> execute(final AsyncParser<T> parser, Runnable cancel) {
        if ($assertionsDisabled || parser != null) {
            EmitterTransform<T> ret = new EmitterTransform<T>(cancel) {
                EmitterTransform<T> self = this;

                protected void transform(LoaderEmitter emitter) throws Exception {
                    super.transform(emitter);
                    parser.parse(this.emitter).setCallback(new FutureCallback<T>() {
                        public void onCompleted(Exception e, T result) {
                            IonRequestBuilder.this.postExecute(AnonymousClass6.this.self, e, result);
                        }
                    });
                }
            };
            getLoaderEmitter(ret);
            return ret;
        }
        throw new AssertionError();
    }

    public ResponseFuture<JsonObject> asJsonObject() {
        return execute(new GsonObjectParser());
    }

    public ResponseFuture<byte[]> asByteArray() {
        return execute(new AsyncParser<byte[]>() {
            public Future<byte[]> parse(DataEmitter emitter) {
                return (Future) new ByteBufferListParser().parse(emitter).then(new TransformFuture<byte[], ByteBufferList>() {
                    protected void transform(ByteBufferList result) throws Exception {
                        setComplete(result.getAllByteArray());
                    }
                });
            }
        });
    }

    public EmitterTransform<File> write(final File file) {
        return execute(new FileDataSink(this.ion.getServer(), file), true, file, new Runnable() {
            public void run() {
                file.delete();
            }
        });
    }

    public IonRequestBuilder setBodyParameter(String name, String value) {
        if (this.bodyParameters == null) {
            this.bodyParameters = new Multimap();
            setBody(new UrlEncodedFormBody(this.bodyParameters));
        }
        if (value != null) {
            this.bodyParameters.add(name, value);
        }
        return this;
    }
}
